﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using CRCDesktop.org.h1.crcDesktop.basicClasses;
using CRCDesktop.org.h1.crcDesktop.util;
using CRCDesktop.org.h1.crcdesktop.util;
using CRCDesktop.org.h1.crcDesktop.comunicacao;


namespace CRCDesktop.org.h1.crcDesktop.business
{
    public class ControleDispositivo : IControleDispositivo
    {

        private ClienteWS clienteWS;
        
        public ControleDispositivo()
        {
            clienteWS = new ClienteWS();
        }

        public int searchDispositivo()
        {
            byte nuDispositivos;
            int qtdDispositivos;
            qtdDispositivos = EasyLabLibrary.SearchDevices(out nuDispositivos);
            return qtdDispositivos;
        }

        /*
         *  - Este método é responsável por acionar um dispositivo conectado a
         *  uma das portas do 
         * 
         **/
        public void ligar(int idCasa, int idDispositivo, int porta, int idAcao)
        {
            //OBS: Antes da execução da ação deve-se verificar o status real do dispositivo
            try
            {
                int portasAligar = 0;

                int bPorta = (int)Math.Pow(2, porta);
                portasAligar = this.getOutPort(idDispositivo) + bPorta;

                EasyLabLibrary.SetPortDirections((byte)idDispositivo, portasAligar);
                EasyLabLibrary.SetOutputPorts((byte)idDispositivo, portasAligar);

                //Atualiza o banco com o status do dispositivo.
                clienteWS.atualizarEquipamento(idDispositivo, porta, idCasa, idAcao);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        /*
         *  - Este método é responsável por desligar um dispositivo conectado a uma
         *  das portas passadas fazendo com que a porta fique com estádo baixo 0V
         * 
         * */
        public void desligar(int idCasa, int idDispositivo, int porta,  int idAcao)
        {
            //TODO: Antes da execução da ação deve-se verificar o status real do dispositivo
            try
            {
                int portaADesligar = 0;
                int bPorta = (int)Math.Pow(2, porta);

                portaADesligar = getOutPort(idDispositivo) - bPorta;

                EasyLabLibrary.SetOutputPorts((byte)idDispositivo, portaADesligar);
                clienteWS.atualizarEquipamento(idDispositivo, porta, idCasa, idAcao);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        /**
         * Verifica se existe dispositivos conectados
         * 
         * */
        public bool validarConexaoDispositivo()
        {
            byte qtdDisp;
            bool isConnected = false;

            EasyLabLibrary.SearchDevices(out qtdDisp);
            if(qtdDisp != 0){
                isConnected = true;
            }
            return isConnected;
        }

        public int getInPort(int idDispositivo)
        {
            int statusPort = 0;
            try
            {
                EasyLabLibrary.GetInPorts((byte)idDispositivo, out statusPort);
            }catch(Exception e){
                Console.WriteLine(e.StackTrace);
            }
            return statusPort;
        }

        /**
         * Retorna a soma binária correspondente as portas ligadas.
         * 
         * */
        public int getOutPort(int idDispositivo)
        {
            int dataOut = 0;
            try
            {
                EasyLabLibrary.GetOutPorts((byte)idDispositivo, out dataOut);
            }catch(Exception e){
                Console.WriteLine(e.StackTrace);
            }
            return dataOut;
        }

        public void desligaAll(){
            EasyLabLibrary.SetOutputPorts(0,0);
        }
        
        /**
         * Este método é responsável por configurar as portas dos sensores como INPUT
         * 
         * */
        public void configurarPortaSaida(int[]dispositivos, string[,] sensores) { 
            try{
                int valPortasAtivadas = 0;
                int somaSensores = 0;
                for (int w = 0; w < dispositivos.Length; w++)
                {
                    for (int i = 0; i < sensores.Length/2; i++)
                    {
                        valPortasAtivadas = Int32.Parse(sensores[i, 0]);
                        somaSensores += (int)Math.Pow(2, valPortasAtivadas);
                    }

                    //Portas saida
                    int portasSaida = 511 - somaSensores;

                    EasyLabLibrary.SetPortDirections((byte)dispositivos[w], portasSaida);
                }
            }catch(Exception e){
                Console.WriteLine(e.StackTrace);
            }
        }
    }
}
